package cn.swing.his.user.webapi.controller;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.swing.his.common.web.JsonPage;
import cn.swing.his.common.web.JsonResult;
import cn.swing.his.pojo.user.dto.ChangeRoleOperationDTO;
import cn.swing.his.pojo.user.dto.DoctorDetailsDTO;
import cn.swing.his.pojo.user.dto.PatientOrderDTO;
import cn.swing.his.pojo.user.vo.*;
import cn.swing.his.user.service.IUserService;
import cn.swing.his.user.webapi.repository.DoctorRepository;
import cn.swing.his.user.webapi.repository.PatientRepository;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.List;

@CrossOrigin
@RestController
@RequestMapping(value = "/users", produces = "application/json;charset=utf-8")
@Api(tags = "用户模块")
@Slf4j
public class UserController {


    @Autowired
    private IUserService userService;

    @Autowired
    DoctorRepository doctorRepository;


    @Autowired
    PatientRepository patientRepository;


    /**
     * 根据医生姓名通过es模糊查询医生信息
     *
     * @return
     */
    @ApiOperation("根据医生姓名通过es模糊查询医生信息")
    @PostMapping("/searchDoctor")
    public JsonResult<Iterable<DoctorListVO>> searchDoctor(String name) {
        List<DoctorListVO> list = userService.doctorList(-1);
        doctorRepository.saveAll(list);
        // 查询 ES中title字段包含"游戏"分词的数据
        Iterable<DoctorListVO> items = doctorRepository.queryDoctorsByNameMatches(name);
        return JsonResult.ok(items);
    }


    /**
     * 根据病人姓名通过es模糊查询病人信息
     *
     * @return
     */
    @ApiOperation("根据病人姓名通过es模糊查询病人信息")
    @PostMapping("/searchPatient")
    public JsonResult<Iterable<PatientListVO>> searchPatient(String name) {
        List<PatientListVO> list = userService.patientList();
        patientRepository.saveAll(list);
        // 查询 ES中title字段包含"游戏"分词的数据
        Iterable<PatientListVO> items = patientRepository.queryPatientsByNameMatches(name);
        return JsonResult.ok(items);
    }

    /**
     * 返回所有患者列表信息
     *
     * @return
     */
    @ApiOperation("患者所有列表信息查询")
    @PostMapping("/patientList")
    public JsonPage<PatientListVO> patientList(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<PatientListVO> list = userService.patientList();
        return JsonPage.restPage(new PageInfo<>(list));
    }


    /**
     * 根据科室返回所有医生列表信息
     *
     * @return
     */
    @ApiOperation("根据科室返回所有医生列表信息")
    @PostMapping("/doctorList")
    public JsonPage<DoctorListVO> doctorList(Integer roomId, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<DoctorListVO> list = userService.doctorList(roomId);
        return JsonPage.restPage(new PageInfo<>(list));
    }

    /**
     * 根据医生ID删除单个医生信息
     *
     * @param id
     * @return
     */
    @ApiOperation("根据ID删除单个医生信息")
    @PostMapping("/deleteSimpleDoctor")
    public JsonResult<Void> deleteSimpleDoctor(Integer id) {
        userService.deleteSimpleDoctorById(id);
        return JsonResult.ok();
    }

    /**
     * 根据患者ID删除单个患者信息
     *
     * @return
     */
    @ApiOperation(value = "根据患者ID删除单个患者信息")
    @PostMapping("/deleteSimplePatientById")
    public JsonResult<Void> deleteSimplePatientById(Integer id) {
        userService.deleteSimplePatientById(id);
        return JsonResult.ok();
    }

    /**
     * 插入单个医生信息
     *
     * @return
     */
    @ApiOperation("插入单个医生信息")
    @PostMapping("/insertSimpleDoctor")
    public JsonResult<Void> insertSimpleDoctor(DoctorDetailsDTO doctorDetailsDTO) {
        log.info("插入单个医生信息：{}", doctorDetailsDTO);
        userService.insertSimpleDoctor(doctorDetailsDTO);
        return JsonResult.ok();
    }

    /**
     * 根据医生ID更新医生信息
     *
     * @param doctorDetailsDTO
     */
    @ApiOperation("根据ID更新医生个人信息")
    @PostMapping("/updateSimpleDoctorDetailsById")
    public JsonResult<Void> updateSimpleDoctorDetailsById(DoctorDetailsDTO doctorDetailsDTO) {
        log.info("{??????????" + doctorDetailsDTO);
        userService.updateSimpleDoctorDetailsById(doctorDetailsDTO);
        return JsonResult.ok();
    }


    /**
     * 插入病人预约情况信息
     *
     * @param patientOrderDTO
     */
    @ApiOperation("插入病人预约情况信息")
    @PostMapping("/insertPatientOrder")
    public JsonResult<Void> insertPatientOrder(PatientOrderDTO patientOrderDTO) {
        userService.insertPatientOrder(patientOrderDTO);
        return JsonResult.ok();
    }


    /**
     * 根据患者身份证号查询个人病历单
     *
     * @param idCard
     * @return
     */
    @ApiOperation("根据患者身份证号查询个人病历单")
    @PostMapping("/selectMedicalRecordList")
    public JsonPage<MedicalRecordVO> selectMedicalRecordList(String idCard, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<MedicalRecordVO> list = userService.selectMedicalRecordList(idCard);
        return JsonPage.restPage(new PageInfo<>(list));
    }


    /**
     * 导出病人信息接口
     */
    @ApiOperation(value = "导出病人明细表")
    @GetMapping("/patientExportList")
    public void patientExportList(HttpServletResponse response) throws Exception {
        // 从数据库查询出所有的数据
        List<PatientListVO> list = userService.patientList();
        log.debug("list：{}", list);

        // 通过工具类创建writer 写出到磁盘路径
//        ExcelWriter writer = ExcelUtil.getWriter(filesUploadPath + "/用户信息.xlsx");
        // 在内存操作，写出到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.addHeaderAlias("id", "id");
        writer.addHeaderAlias("name", "患者名");
        writer.addHeaderAlias("gender", "性别");
        writer.addHeaderAlias("telephone", "电话");
        writer.addHeaderAlias("description", "描述");
        writer.addHeaderAlias("idCard", "身份证号");
        writer.addHeaderAlias("address", "家庭地址");
        writer.addHeaderAlias("personality", "民族");
        writer.addHeaderAlias("allergen", "过敏原");
        writer.addHeaderAlias("medicalInsurance", "医保号");
        writer.addHeaderAlias("bloodType", "血型");
        writer.addHeaderAlias("email", "邮箱");
        writer.addHeaderAlias("gmtCreated", "注册时间");
        // 一次性写出list内的对象到excel，使用默认样式，强制输出标题
        writer.write(list, true);
        // 设置浏览器响应的格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("病人列表所有信息", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        out.close();
        writer.close();
    }


    /**
     * 导出医生信息接口
     */
    @ApiOperation(value = "导出医生明细表")
    @GetMapping("/doctorExportList")
    public void doctorExportList(HttpServletResponse response) throws Exception {
        // 从数据库查询出所有的数据
        Integer roomId = -1;
        List<DoctorListVO> list = userService.doctorList(roomId);
        log.debug("list：{}", list);
        // 通过工具类创建writer 写出到磁盘路径
//        ExcelWriter writer = ExcelUtil.getWriter(filesUploadPath + "/用户信息.xlsx");
        // 在内存操作，写出到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.addHeaderAlias("id", "id");
        writer.addHeaderAlias("name", "医生名");
        writer.addHeaderAlias("gender", "性别");
        writer.addHeaderAlias("telephone", "电话");
        writer.addHeaderAlias("description", "描述");
        writer.addHeaderAlias("idCard", "身份证号");
        writer.addHeaderAlias("address", "家庭地址");
        writer.addHeaderAlias("professionalTitle", "职称");
        writer.addHeaderAlias("roomId", "科室号");
        writer.addHeaderAlias("medicalInsurance", "医保号");
        writer.addHeaderAlias("email", "邮箱");
        writer.addHeaderAlias("gmtCreated", "注册时间");

        // 一次性写出list内的对象到excel，使用默认样式，强制输出标题
        writer.write(list, true);
        // 设置浏览器响应的格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("医生列表所有信息", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        out.close();
        writer.close();
    }

    /**
     * 根据病人身份证号获取单个病人所有个人信息
     *
     * @param idCard
     * @return
     */
    @ApiOperation(value = "根据病人身份证号获取单个病人所有个人信息")
    @PostMapping("/selectSimplePatientDetails")
    public JsonResult<PatientDetailsVO> selectSimplePatientDetails(String idCard) {
        PatientDetailsVO patientDetails = userService.selectSimplePatientDetails(idCard);
        return JsonResult.ok(patientDetails);
    }


    /**
     * 根据医生身份证号获取单个病人所有个人信息
     *
     * @param idCard
     * @return
     */
    @ApiOperation(value = "根据医生身份证号获取单个医生所有个人信息")
    @PostMapping("/selectSimpleDoctorDetails")
    public JsonResult<DoctorDetailsVO> selectSimpleDoctorDetails(String idCard) {
        DoctorDetailsVO doctorDetails = userService.selectSimpleDoctorDetails(idCard);
        return JsonResult.ok(doctorDetails);
    }


    /**
     * 返回科室中所有列表信息
     *
     * @return
     */
    @ApiOperation(value = "返回科室中所有列表信息")
    @PostMapping("/selectRoomList")
    public JsonResult<List<RoomListVO>> selectRoomList() {
        List<RoomListVO> roomList = userService.selectRoomList();
        return JsonResult.ok(roomList);
    }


    /**
     * 查询出所有角色列表信息
     *
     * @return
     */
    @ApiOperation(value = "查询出所有角色列表信息")
    @PostMapping("/selectRoleList")
    public JsonResult<List<RoleListVO>> selectRoleList() {
        List<RoleListVO> roleList = userService.selectRoleList();
        return JsonResult.ok(roleList);
    }


    /**
     * 插入单个角色信息
     *
     * @param name
     */
    @ApiOperation(value = "插入单个角色信息")
    @PostMapping("/insertRole")
    public JsonResult<Void> insertRole(String name) {
        userService.insertRole(name);
        return JsonResult.ok();
    }


    /**
     * 根据角色ID删除单个角色信息
     *
     * @param id
     */
    @ApiOperation(value = "根据角色ID删除单个角色信息")
    @PostMapping("/deleteRoleById")
    public JsonResult<Void> deleteRoleById(Integer id) {
        log.info("id" + id);
        userService.deleteRoleById(id);
        return JsonResult.ok();
    }

    /**
     * 返回所有权限列表信息
     *
     * @return
     */
    @ApiOperation(value = "返回所有权限列表信息")
    @PostMapping("/selectPermissionList")
    public JsonResult<List<PermissionListVO>> selectPermissionList() {
        List<PermissionListVO> permissionListVOS = userService.selectPermissionList();
        return JsonResult.ok(permissionListVOS);
    }


    /**
     * 根据医生ID查询医生姓名
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "根据ID获取医生姓名")
    @PostMapping("/selectDoctorNameById")
    public JsonResult<DoctorSimpleVO> selectDoctorNameById(Integer id) {
        DoctorSimpleVO result = userService.selectDoctorNameById(id);
        return JsonResult.ok("查询成功", result);
    }


    /**
     * 根据ID批量删除医生列表信息
     *
     * @param ids
     */
    @ApiOperation(value = "根据ID批量删除医生列表信息")
    @PostMapping("/deleteDoctorsByIds")
    public JsonResult<Void> deleteDoctorsByIds(Integer[] ids) {
        userService.deleteDoctorsByIds(ids);
        return JsonResult.ok();
    }


    /**
     * 根据ID批量删除病人列表信息
     *
     * @param ids
     */
    @ApiOperation(value = "根据ID批量删除病人列表信息")
    @PostMapping("/deletePatientsByIds")
    public JsonResult<Void> deletePatientsByIds(Integer[] ids) {
        userService.deletePatientsByIds(ids);
        return JsonResult.ok();
    }


    /**
     * 根据ID修改医生个人密码
     *
     * @param id
     */
    @ApiOperation(value = "根据ID修改医生个人密码")
    @PostMapping("/updateDoctorPasswordById")
    public JsonResult<Void> updateDoctorPasswordById(Integer id, String password) {
        userService.updateDoctorPasswordById(id, password);
        return JsonResult.ok();
    }


    /**
     * 根据病人ID返回病人预约信息
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "根据病人ID返回病人预约信息")
    @PostMapping("/orderDetailsById")
    public JsonResult<List<OrderDetailsVO>> orderDetailsById(Integer id) {
        List<OrderDetailsVO> orderDetailsVOS = userService.orderDetailsById(id);
        return JsonResult.ok(orderDetailsVOS);
    }


    /**
     * 根据角色ID获取该角色所有权限信息
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "根据角色ID获取该角色所有权限信息")
    @PostMapping("/permissionListById")
    public List<PermissionListVO> permissionListById(Integer id) {
        List<PermissionListVO> permissionsById = userService.permissionListById(id);
        return permissionsById;
    }


    /**
     * 根据角色ID插入角色-操作关联信息
     *
     * @param changeRoleOperations
     * @return
     */
    @ApiOperation(value = "根据角色ID插入角色-操作关联信息")
    @PostMapping("/changeRoleOperationById")
    public JsonResult<Void> changeRoleOperation(@RequestBody List<ChangeRoleOperationDTO> changeRoleOperations) {
        log.info("changeRoleOperations>>>??????????" + changeRoleOperations);
        userService.changeRoleOperation(changeRoleOperations);
        return JsonResult.ok();
    }

    /**
     * 根据医生id和菜单级别查看不同角色下不同的导航栏菜单
     *
     * @param
     * @return
     */
    @ApiOperation(value = "根据医生id查看不同角色下不同的导航栏菜单")
    @PostMapping("/selectDoctorMenuById")
    public JsonResult<List<DoctorMenuVO>> selectDoctorMenuById(Integer id) {
        log.info("根据医生id查看不同角色下不同的导航栏菜单下医生ID为" + id);
        List<DoctorMenuVO> doctorMenuVO = userService.selectDoctorMenuById(id);
        log.info("根据医生id查看不同角色下不同的导航栏菜单下医生doctorMenuVO为" + doctorMenuVO);
        return JsonResult.ok(doctorMenuVO);
    }


    /**
     * 根据科室ID查询单个科室详细信息
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "根据科室ID查询单个科室详细信息")
    @PostMapping("/selectRoomDetailById")
    public JsonResult<RoomDetailsVO> selectRoomDetailById(Integer id) {
        RoomDetailsVO doctorMenuVO = userService.selectRoomDetailById(id);
        return JsonResult.ok(doctorMenuVO);
    }

}
